package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserRoleService;
import com.ruoyi.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Validator;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 用户 业务层处理
 *
 * @author ruoyi
 */
@Service
public class SysUserServiceImpl implements ISysUserService {
	private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);
	@Resource
	protected Validator validator;
	@Resource
	private SysUserMapper userMapper;
	@Resource
	private SysRoleMapper roleMapper;
	@Resource
	private SysUserRoleMapper userRoleMapper;
	@Resource
	private ISysConfigService configService;
	@Resource
	private ISysUserRoleService userRoleService;
	@Resource
	private ISysRoleService roleService;

	/**
	 * 根据条件分页查询用户列表
	 * TODO 可以删除
	 *
	 * @param user 用户信息
	 * @return 用户信息集合信息
	 */
	@Override
	public List<SysUser> selectUserList(SysUser user) {
		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(new SysUser());
		queryWrapper.isNotNull(SysUser::getUserId);
		return userMapper.selectList(queryWrapper);
	}

	/**
	 * 根据条件分页查询已分配用户角色列表
	 *
	 * @param user 用户信息
	 * @return 用户信息集合信息
	 */
	@Override
	@DataScope(deptAlias = "d", userAlias = "u")
	public List<SysUser> selectAllocatedList(SysUser user) {
		return userMapper.selectAllocatedList(user);
	}

	/**
	 * 根据条件分页查询未分配用户角色列表
	 *
	 * @param user 用户信息
	 * @return 用户信息集合信息
	 */
	@Override
	@DataScope(deptAlias = "d", userAlias = "u")
	public List<SysUser> selectUnallocatedList(SysUser user) {
		return userMapper.selectUnallocatedList(user);
	}

	/**
	 * 分页查询用户
	 * TODO 可以删除
	 *
	 * @param pageDomain 分页数据
	 * @param user       查询条件
	 * @return Page
	 */
	@Override
	public Page selectPage(PageDomain pageDomain, SysUser user) {
		System.out.println(pageDomain);
		try {
			LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(new SysUser());
			queryWrapper.isNotNull(SysUser::getUserId);
			Page page = userMapper.selectPage(pageDomain.getPage(), queryWrapper);
			return page;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 通过用户名查询用户
	 *
	 * @param userName 用户名
	 * @return 用户对象信息
	 */
	@Override
	public SysUser selectUserByUserName(String userName) {
		if (StringUtils.isEmpty(userName)) {
			return null;
		}
		try {
			LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(new SysUser());
			queryWrapper.eq(SysUser::getUserName, userName);
			SysUser user = userMapper.selectOne(queryWrapper);
			List<SysRole> roleList = roleMapper.selectRolePermissionByUserId(user.getUserId());
			user.setRoles(roleList);
			return user;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 通过用户名查询用户
	 *
	 * @param userName 用户名
	 * @return 用户对象信息
	 */
	@Override
	public SysUser selectByUserName(String userName) {
		if (StringUtils.isEmpty(userName)) {
			return null;
		}
		try {
			LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(new SysUser());
			queryWrapper.eq(SysUser::getUserName, userName);
			return userMapper.selectOne(queryWrapper);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 通过用户ID查询用户
	 *
	 * @param userId 用户ID
	 * @return 用户对象信息
	 */
	@Override
	public SysUser selectUserById(Long userId) {
		if (Objects.isNull(userId)) {
			return null;
		}
		try {
			SysUser user = userMapper.selectById(userId);
			List<SysUserRole> userRoleList = userRoleService.getByUserId(userId);
			user.setRoles(roleService.selectRolesByUserId(userId));
			user.setRoleIds(roleService.selectRoleIdsByUserId(userId));
			return user;
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 通过用户ID查询用户
	 *
	 * @param userId 用户ID
	 * @return 用户对象信息
	 */
	@Override
	public SysUser selectById(Long userId) {
		if (Objects.isNull(userId)) {
			return null;
		}
		try {
			return userMapper.selectById(userId);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 校验用户名称是否唯一
	 *
	 * @param user 用户信息
	 * @return 结果
	 */
	@Override
	public boolean checkUserNameUnique(SysUser user) {
//		Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
//
//		SysUser info = userMapper.checkUserNameUnique(user.getUserName());
//		if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
//
//		}
//		return UserConstants.UNIQUE;
		if (Objects.isNull(user)) {
			return UserConstants.NOT_UNIQUE;
		}
		if (StringUtils.isEmpty(user.getUserName())) {
			return UserConstants.NOT_UNIQUE;
		}
		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(new SysUser());
		queryWrapper.eq(SysUser::getUserName, user.getUserName());
		if (!Objects.isNull(user.getUserId())) {
			queryWrapper.ne(SysUser::getUserId, user.getUserId());
		}
		boolean exists = userMapper.exists(queryWrapper);
		if (!exists) {
			return UserConstants.UNIQUE;
		} else {
			return UserConstants.NOT_UNIQUE;
		}
	}

	/**
	 * 校验手机号码是否唯一
	 *
	 * @param user 用户信息
	 * @return
	 */
	@Override
	public boolean checkPhoneUnique(SysUser user) {
//		Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
//		SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
//		if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
//			return UserConstants.NOT_UNIQUE;
//		}
//		return UserConstants.UNIQUE;

		if (Objects.isNull(user)) {
			return UserConstants.NOT_UNIQUE;
		}
		if (StringUtils.isEmpty(user.getPhonenumber())) {
			return UserConstants.NOT_UNIQUE;
		}
		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(new SysUser());
		queryWrapper.eq(SysUser::getPhonenumber, user.getPhonenumber());
		if (!Objects.isNull(user.getUserId())) {
			queryWrapper.ne(SysUser::getUserId, user.getUserId());
		}
		boolean exists = userMapper.exists(queryWrapper);
		if (!exists) {
			return UserConstants.UNIQUE;
		} else {
			return UserConstants.NOT_UNIQUE;
		}
	}

	/**
	 * 校验email是否唯一
	 *
	 * @param user 用户信息
	 * @return
	 */
	@Override
	public boolean checkEmailUnique(SysUser user) {
//		Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
//		SysUser info = userMapper.checkEmailUnique(user.getEmail());
//		if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
//			return UserConstants.NOT_UNIQUE;
//		}
//		return UserConstants.UNIQUE;

		if (Objects.isNull(user)) {
			return UserConstants.NOT_UNIQUE;
		}
		if (StringUtils.isEmpty(user.getEmail())) {
			return UserConstants.NOT_UNIQUE;
		}
		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>(new SysUser());
		queryWrapper.eq(SysUser::getEmail, user.getEmail());
		if (!Objects.isNull(user.getUserId())) {
			queryWrapper.ne(SysUser::getUserId, user.getUserId());
		}
		boolean exists = userMapper.exists(queryWrapper);
		if (!exists) {
			return UserConstants.UNIQUE;
		} else {
			return UserConstants.NOT_UNIQUE;
		}
	}

	/**
	 * 校验用户是否允许操作
	 *
	 * @param user 用户信息
	 */
	@Override
	public void checkUserAllowed(SysUser user) {
		if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) {
			throw new ServiceException("不允许操作超级管理员用户");
		}
	}

	/**
	 * 校验用户是否有数据权限
	 *
	 * @param userId 用户id
	 */
	@Override
	public void checkUserDataScope(Long userId) {
//		if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
//			SysUser user = new SysUser();
//			user.setUserId(userId);
//			List<SysUser> users = SpringUtils.getAopProxy(this).selectUserList(user);
//			if (StringUtils.isEmpty(users)) {
//				throw new ServiceException("没有权限访问用户数据！");
//			}
//		}
	}

	/**
	 * 新增保存用户信息和用户角色信息
	 *
	 * @param user 用户信息
	 * @return 结果
	 */
	@Override
	@Transactional
	public int insertUser(SysUser user) {
		if (Objects.isNull(user)) {
			return -1;
		}
		try {
			int result = userMapper.insert(user);
			Long userId = user.getUserId();
			if (!Objects.isNull(user.getRoleIds()) && user.getRoleIds().length > 0) {
				userRoleService.insertByUserIdAndRoleIds(userId, user.getRoleIds());
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
	}

	@Override
	public boolean registerUser(SysUser user) {
		return false;
	}

	/**
	 * 修改保存用户信息
	 *
	 * @param user 用户信息
	 * @return 结果
	 */
	@Override
	@Transactional
	public int updateUser(SysUser user) {
		if (Objects.isNull(user)) {
			return -1;
		}
		try {
			Long userId = user.getUserId();
			userRoleService.deleteByUserId(userId);
			userRoleService.insertByUserIdAndRoleIds(userId, user.getRoleIds());
			int result = userMapper.updateById(user);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
	}

	/**
	 * 用户授权角色
	 *
	 * @param userId  用户ID
	 * @param roleIds 角色组
	 */
	@Override
	@Transactional
	public void insertUserAuth(Long userId, Long[] roleIds) {
		if (Objects.isNull(userId)) {
			return;
		}
		if (Objects.isNull(roleIds)) {
			return;
		}
		try {
			userRoleService.deleteByUserId(userId);
			userRoleService.insertByUserIdAndRoleIds(userId, roleIds);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 修改用户状态
	 *
	 * @param user 用户信息
	 * @return 结果
	 */
	@Override
	public int updateUserStatus(SysUser user) {
		if (Objects.isNull(user)) {
			return -1;
		}
		try {
			LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>(new SysUser());
			updateWrapper.eq(SysUser::getStatus, user.getStatus());
			updateWrapper.set(SysUser::getStatus, user.getStatus());
			return userMapper.update(null, updateWrapper);
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * 修改用户基本信息
	 * TODO
	 *
	 * @param user 用户信息
	 * @return 结果
	 */
	@Override
	public int updateUserProfile(SysUser user) {
		return 1;
	}

	/**
	 * 修改用户头像
	 *
	 * @param userName 用户名
	 * @param avatar   头像地址
	 * @return 结果
	 */
	@Override
	public boolean updateUserAvatar(String userName, String avatar) {
		return true;
	}

	/**
	 * 重置用户密码
	 *
	 * @param user 用户信息
	 * @return 结果
	 */
	@Override
	public int resetPwd(SysUser user) {
		return 1;
	}

	/**
	 * 重置用户密码
	 *
	 * @param userName 用户名
	 * @param password 密码
	 * @return 结果
	 */
	@Override
	public int resetUserPwd(String userName, String password) {
		return 1;
	}

	/**
	 * 新增用户角色信息
	 *
	 * @param user 用户对象
	 */
	public void insertUserRole(SysUser user) {
		this.insertUserRole(user.getUserId(), user.getRoleIds());
	}

	/**
	 * 新增用户角色信息
	 *
	 * @param userId  用户ID
	 * @param roleIds 角色组
	 */
	public void insertUserRole(Long userId, Long[] roleIds) {
		if (Objects.isNull(userId)) {
			return;
		}
		if (Objects.isNull(roleIds)) {
			return;
		}
		try {
			insertUserAuth(userId, roleIds);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 通过用户ID删除用户
	 *
	 * @param userId 用户ID
	 * @return 结果
	 */
	@Override
	@Transactional
	public int deleteUserById(Long userId) {
		if (Objects.isNull(userId)) {
			return -1;
		}
		try {
			int result = userMapper.deleteById(userId);
			userRoleService.deleteByUserId(userId);
			return result;
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * 批量删除用户信息
	 *
	 * @param userIds 需要删除的用户ID
	 * @return 结果
	 */
	@Override
	@Transactional
	public int deleteUserByIds(Long[] userIds) {
		if (Objects.isNull(userIds)) {
			return -1;
		}
		try {
			userRoleService.deleteByUserIds(userIds);
			return userMapper.deleteBatchIds(Arrays.asList(userIds));
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * 导入用户数据
	 * TODO
	 *
	 * @param userList        用户数据列表
	 * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
	 * @param operName        操作用户
	 * @return 结果
	 */
	@Override
	public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName) {
		if (StringUtils.isNull(userList) || userList.size() == 0) {
			throw new ServiceException("导入用户数据不能为空！");
		}
		int successNum = 0;
		int failureNum = 0;
		StringBuilder successMsg = new StringBuilder();
		StringBuilder failureMsg = new StringBuilder();
		String password = configService.selectConfigByKey("sys.user.initPassword");
		for (SysUser user : userList) {
			try {
				// 验证是否存在这个用户
				SysUser u = selectUserByUserName(user.getUserName());
				if (StringUtils.isNull(u)) {
					BeanValidators.validateWithException(validator, user);
					user.setPassword(SecurityUtils.encryptPassword(password));
					user.setCreateBy(operName);
					this.insertUser(user);
					successNum++;
					successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 导入成功");
				} else if (isUpdateSupport) {
					BeanValidators.validateWithException(validator, user);
					checkUserAllowed(user);
					checkUserDataScope(user.getUserId());
					user.setUpdateBy(operName);
					this.updateUser(user);
					successNum++;
					successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 更新成功");
				} else {
					failureNum++;
					failureMsg.append("<br/>" + failureNum + "、账号 " + user.getUserName() + " 已存在");
				}
			} catch (Exception e) {
				failureNum++;
				String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败：";
				failureMsg.append(msg + e.getMessage());
				log.error(msg, e);
			}
		}
		if (failureNum > 0) {
			failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
			throw new ServiceException(failureMsg.toString());
		} else {
			successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
		}
		return successMsg.toString();
	}
}
